// 后台代码
// 后台代码可以发送异步请求，但是不能操作DOM

class Credit {
  // constructor
  constructor() {
    /*
     * 插件当前的状态
     * wait    : 等待执行任务
     * loading : 正在执行任务
     * complate: 任务执行完成
     *
    */
    this.status = 'wait'

    // 前端传输信息载体
    this.port = null
    // 页面id
    this.id  = null
    this.isInit = false

    // 服务器地址
    this.server_url = 'http://localhost:3000/remote/'

    // 接口
    this.interface = { //
      // 请求任务
      requestTask: 'requestTask',
      // 接受并开始执行任务
      resolveTask: 'resolveTask',
      // 拒绝接受任务
      rejectTask: 'rejectTask',
      // 任务执行成功
      doneTask: 'doneTask',
      // 任务执行失败
      failTask: 'failTask'
    }

    this.url = 'https://ipcrs.pbccrc.org.cn/'
    this.url_regex = '*://ipcrs.pbccrc.org.cn/*'

    // 轮询请求任务计时器
    this.requestTaskTimer = null
    // 轮询请求任务间隔
    this.requestTaskSpeed = 3 * 1000 // 1秒
    // 任务超时计时器
    this.runTaskTimer = null
    // 任务超时时间
    this.runTaskLimit = 60 * 1000 // 60秒
    
    // 任务清单,终端发来的任务只能是此中之一
    this.legalTaskList = [
      /* ========== 页面跳转 ========== */
      // 跳转到首页
      '2index',
      // 跳转到登录页面
      '2login',
      // 跳转到注册页面
      '2reg',
      // 跳转到找回密码页面
      '2findPassword',
      // 跳转到登录后的欢迎页
      '2welcome',
      // 跳转到申请报告页面
      '2applicationReport',
      // 跳转到获取报告页面
      '2getReport',
      // 退出
      'quit',
      
      /* ========== 获取页面元素 ========== */
      // 获取登录页图片验证码,base64格式
      'getLoginValidImage',
      // 获取注册页图片验证码,base64格式
      'getRegStep1ValidImage',
      // 获取注册步骤二手机验证码
      'getStep2ValidCode',
      // 获取信用报告手机验证码
      'getReportValidCode',
      // 申请问卷
      'applicationReport',
      // 获取
      'getReport',

      /* ========== 填充表单 ========== */
      'inputLoginForm',
      // 填写问卷
      'inputQues',
      // 填写注册步骤一表单
      'inputRegStep1Form',
      // 填写注册步骤二表单
      'inputRegStep2Form',
      // 填写征信报告验证码表单
      'inputReportForm'
    ]

    this.init()
  }
  
  init() {
    let that = this

    chrome.tabs.query({url: this.url_regex}, function(tabs) {
      
      if (!tabs.length) { // 如果当前窗口没有征信页面则打开一个
        chrome.tabs.create({url: that.url}, function(tab) {
          that.load(tab)
        })
      } else {
        that.load(tabs[0])
      }

    })

    this.getPort()

  }
  
  // 页面load事件
  load(tab) {
    let that = this

    that.id = tab.id

    if (tab.status === 'complete') { // 如果已经加载完成则连接前台代码，否则监听load事件
      this.connect(tab)
      return
    }
    
    // 监听load事件
    chrome.tabs.onUpdated.addListener(function(id, changeInfo, tab) {
      if (that.id === id && tab.status === 'complete') { // 加载完成
        console.log('加载完成啦')

        chrome.tabs.onUpdated.removeListener()

        that.connect(tab)
      }
    })

  }
  
  // 连接前台代码
  connect(tab) {
    let that = this

    this.port = chrome.tabs.connect(tab.id)
    console.log('开启连接')
    
    // 监听前端代码事件
    this.contentEvent()
    // 轮询服务器任务
    if (!this.isInit) {
      this.requestTask()
      this.isInit = true
    }
  }
  
  // 注册前台代码事件
  contentEvent() {
    let that = this

    // 接受消息事件
    this.port.onMessage.addListener(function(data) {
      console.log('接受消息事件 ' + new Date().getTime())
      console.log(data)
     
      // 如果status为loading则表示此时期望的下一次反馈的结果为发布任务的结果
      if (that.status === 'loading') {
        that.status = 'complate'

        if (data.status) {

          that.sendMessageToServer({
            req: that.interface.doneTask,
            data: data,
            done: function() {
              that.requestTask()
              that.status = 'wait'
            }
          })
          
        } else {
          that.sendMessageToServer({
            req: that.interface.failTask,
            data: data,
            done: function() {
              that.requestTask()
              that.status = 'wait'
            }
          })
        }

      }

    })

    // 断开连接事件
    this.port.onDisconnect.addListener(function() { // 断开连接事件
      console.log('断开连接')
      // 刷新页面
      // that.init()
      
      // 重新加载插件
      // chrome.runtime.reload()
    })
  }
  
  // 因为报告页面是弹出来的,所以要监听
  getPort() {
    let that = this

    chrome.runtime.onMessage.addListener(function(data, sender, sendResponse){
      console.log(data)

      if (data.status) {

        that.sendMessageToServer({
          req: that.interface.doneTask,
          data: data,
          done: function() {
            that.requestTask()
            that.status = 'wait'
          }
        })
        
      } else {

        that.sendMessageToServer({
          req: that.interface.failTask,
          data: data,
          done: function() {
            that.requestTask()
            that.status = 'wait'
          }
        })

      }



      sendResponse(true)

    })

  }

  // 发送前端任务
  sendTask(res, cb) {
    let that = this

    console.log('前台代码接受到了任务啦')
    
    // 向插件发布任务
    this.port.postMessage(res.data)
    
    // 此时等待前端反馈结果
    this.status = 'loading'

    clearTimeout(that.runTaskTimer)

  }
  
  // 向服务器请求任务
  requestTask() {
    let that = this
    
    // 做轮询一定要先清除计时器,不然不可逆!
    that.stopRequestTask()
    that.requestTaskTimer = setInterval(Polling, that.requestTaskSpeed)


    function Polling() {

      that.sendMessageToServer({
        req: that.interface.requestTask,
        done: function(res) {
          // 判断服务器是否有任务
          if (!res.status) {
            return
          }

          // 判断任务的有效性
          if (!that.checkTask(res.data.task)) {

            that.sendMessageToServer({
              req: that.interface.rejectTask,
              data: $.extend({}, res.data, {
                      message: '任务无效'
                    })
            })

            return
          }
          
          // 如果请求到了任务，则关闭轮询，开始执行任务
          that.stopRequestTask()

          that.runTask(res, function() {
            // 告诉服务器我已经开始执行任务了
            that.sendMessageToServer({req: that.interface.resolveTask})

          })
        }
      })

    }
  }
  
  // 停止向服务器请求任务
  stopRequestTask() {
    clearInterval(this.requestTaskTimer)
  }
  
  // 开始执行任务
  runTask(res, cb) {
    let that = this
    
    // 发送任务给前端代码
    this.sendTask(res)

    // 开启任务超时计时器
    this.runTaskTimer = setTimeout(function() {
      that.stopTask()
      that.requestTask()

    }, that.runTaskLimit)

    cb && cb(this)
  }
  
  // 停止执行任务
  stopTask(cb) {
    let that = this

    this.status = 'wait'

    console.log('任务超时啦')

    clearTimeout(that.runTaskTimer)

    that.sendMessageToServer({
      req: that.interface.failTask,
      data: '任务超时'
    })

    cb && cb(that)
  }
  
  // 检验任务有效性
  checkTask(task) {
    let i   = 0,
        len = this.legalTaskList.length

    for (; i < len; i++) {
      if (this.legalTaskList[i] === task) {
        return true
      }
    }

    return false
  }
  
  // 向服务器发送消息
  sendMessageToServer(config) {

    let that = this

    config.req  = config.req || ''
    config.data = config.data || {}
    config.done = config.done || function() {}
    config.fail = config.fail || function() {}

    $.ajax({
      url: that.server_url + config.req,
      data: config.data
    })
    .done(function(res) {
      config.done(res)
    })
    .fail(function(res) {
      config.fail(res)
    })
    .always(function() {
      // console.log("complete")
    })
            

  }
}

let c = new Credit()